/*
 * @Author: zipeng 1134348223@qq.com
 * @Date: 2024-03-01 20:05:09
 * @LastEditors: zipeng 1134348223@qq.com
 * @LastEditTime: 2024-11-07 23:17:20
 * @FilePath: \mycode\stack.c
 * @Description: 
 * 
 * Copyright (c) 2024 by HuaWeiTecho, All Rights Reserved. 
 */
#include "stack.h"
#include "string.h"
#include "def.h"


uint32_t g_adptStackBuffer[ADPT_STACK_SIZE] = { 0 };
ADPT_StackStru g_adptStack = {
    .ptrBuf = g_adptStackBuffer,
    .size = 0,
    .depth = 0,
    .writepoint = 0,
};

/**
 * @brief: 环形栈初始化
 * @param {ADPT_StackStru*} ptrStack
 * @param {uint32_t} *ptrBuf
 * @param {int32_t} size
 * @return 0成功，-1失败
 */
int32_t ADPT_StackInit(ADPT_StackStru* ptrStack, uint32_t *ptrBuf, int32_t size)
{
    RETURN_ERROR_IF (ptrStack == NULL || ptrBuf == NULL || size <= 0);
    ptrStack->ptrBuf = ptrBuf;
    ptrStack->size = size;
    ptrStack->depth = 0;
    ptrStack->writepoint = 0;
    return ADPT_TRUE;
}

/**
 * @brief: 环形栈清除
 * @param {ADPT_StackStru*} ptrStack
 * @return 0成功，-1失败
 */
int32_t ADPT_StackClear(ADPT_StackStru* ptrStack)
{
    RETURN_ERROR_IF (ptrStack == NULL);
    ptrStack->depth = 0;
    ptrStack->writepoint = 0;
    memset(ptrStack->ptrBuf, 0, ptrStack->size);
    return ADPT_TRUE;
}

/**
 * @brief: 环形栈压栈
 * @param {ADPT_StackStru*} ptrStack
 * @param {uint32_t} data
 * @return 0成功，-1失败
 */
int32_t ADPT_StackPush(ADPT_StackStru* ptrStack, uint32_t data)
{
    RETURN_ERROR_IF (ptrStack == NULL);
    int32_t index = ptrStack->writepoint; // 获取栈顶
    ptrStack->ptrBuf[index] = data; // 数据入栈
    ptrStack->writepoint++; // 栈生长
    if (ptrStack->writepoint >= ptrStack->size) {
        ptrStack->writepoint = 0;
    }
    if (ptrStack->depth < ptrStack->size) {
        ptrStack->depth++;
    }
    return ADPT_TRUE;
}
/**
 * @brief: 环形栈出栈
 * @param {ADPT_StackStru*} ptrStack
 * @param {uint32_t} *ptrData
 * @return 0成功，-1失败
 */
int32_t ADPT_StackPop(ADPT_StackStru* ptrStack, uint32_t *ptrData)
{
    RETURN_ERROR_IF (ptrStack == NULL || ptrData == NULL || ptrStack->depth <= 0);
    int32_t index = ptrStack->writepoint - 1; // stack top
    if (index < 0) {
        index = ptrStack->size - 1;
    }
    *ptrData = ptrStack->ptrBuf[index];
    ptrStack->writepoint = index;
    if (ptrStack->depth >= 0) {
        ptrStack->depth--;
    }
    return ADPT_TRUE;
}
/**
 * @brief: 只取环形栈顶数据
 * @param {ADPT_StackStru*} ptrStack
 * @param {uint32_t} *ptrData
 * @return 0成功，-1失败
 */
int32_t ADPT_StackTop(ADPT_StackStru* ptrStack, uint32_t *ptrData)
{
    RETURN_ERROR_IF (ptrStack == NULL || ptrData == NULL || ptrStack->depth <= 0);
    int32_t index = ptrStack->writepoint - 1; // stack top
    if (index < 0) {
        index = ptrStack->size - 1;
    }
    *ptrData = ptrStack->ptrBuf[index];
    return ADPT_TRUE;
}

#if 0
 int main(void)
 {
    ADPT_StackInit(&g_adptStack, g_adptStackBuffer, ARRAY_SIZE(g_adptStackBuffer));
    printf("hello world\r\n");

    for (int32_t i = 0; i < ARRAY_SIZE(g_adptStackBuffer); i++) {
        ADPT_StackPush(&g_adptStack, i);
    }
    int32_t topData = 0, dataOut = 0;
    ADPT_StackTop(&g_adptStack, &topData);
    printf("topData = %d\r\n", topData);
    for (int32_t i = ARRAY_SIZE(g_adptStackBuffer); i > 0; i--) {
        ADPT_StackPop(&g_adptStack, &dataOut);
        ADPT_StackTop(&g_adptStack, &topData);
        printf("pushData = %d, writepoint:%d\r\n", topData, g_adptStack.writepoint);
    }
    return ADPT_TRUE;
 }
#endif
